#!/usr/bin/env python

if __name__ != '__main__':
    raise Exception('Do not import this file!  Run it from the shell.')

import os
import sys
import time

from framegrabber import is_device, FrameGrabber
from recorder import Recorder

DEBUG_MODE = True

def dprint(msg, fileobj=sys.stdout, newline=True):
    '''
    Prints messages to fileobj if DEBUG_MODE is True.
    '''
    nlchar = '\n' if newline else ''
    if DEBUG_MODE:
        fileobj.write(msg + nlchar)
        fileobj.flush()

def parse_args(args):
    '''
    Parse, process and validate command line arguments.
    '''
    from optparse import OptionParser
    from tempfile import mkdtemp
    
    parser = OptionParser()

    parser.add_option('-d', '--device', metavar='DEV', dest='device',
        default='/dev/video0', help='video input device name (ex. /dev/video0)')
    parser.add_option('-l', '--label', metavar='LBL', dest='label',
        default='', help='a text label/name for the device')
    parser.add_option('-s', '--size', metavar='RES', dest='size',
        default='320x240', help='recording resolution (ex. 320x240)')
    parser.add_option('-r', '--rate', metavar='FPS', dest='framerate',
        default='1', help='frame rate to record frames at in frames/second')
    parser.add_option('-p', '--path', metavar='DIR', dest='path',
        default=None, help='path to directory to store frame within')

    opts, args = parser.parse_args(args)
    
    settings = {}

    # validate device
    if not is_device(opts.device):
        parser.error('specified video input device does not exist')
    else:
        settings['device'] = opts.device

    # validate label
    settings['label'] = opts.label.strip() if opts.label.strip() else None

    # validate size
    if 'x' not in opts.size:
        parser.error('error parsing video resolution')
    str_size = opts.size.split('x')
    if len(str_size) != 2:
        parser.error('error parsing video resolution')
    try:
        settings['size'] = int(str_size[0]), int(str_size[1])
    except ValueError:
        parser.error('error parsing video resolution')

    try:
        settings['rate'] = int(opts.framerate)
        if settings['rate'] <= 0:
            parser.error('framerate out of range, must be above zero.')
    except ValueError:
        parser.error('error parsing framerate')

    # validate storage directory
    if opts.path is None:
        opts.path = mkdtemp(prefix='opencircuit_')
    try:
        if not os.path.isdir(opts.path):
            os.makedirs(opts.path)
    except:
        parser.error('storage directory does not exist and cannot be created.')
    settings['path'] = opts.path
    
    return settings

frame_count = 0, 0

def on_frame_added(timestamp):
    global frame_count
    frame_count = frame_count[0] + 1, frame_count[1]
    status_print()

def on_motion_detected(value):
    global frame_count
    frame_count = frame_count[0], frame_count[1] + 1
    status_print()

def status_print():
    stat = 'Static/Motion/Total = %d/%d/%d' % (
        frame_count[0], frame_count[1], sum(frame_count))
    dprint(stat.ljust(70, ' ') + '\r', newline=False)
    
settings = parse_args(sys.argv)

dprint('OpenCircuit Recorder Settings:')
dprint('------------------------------')
dprint('  Video Device: %s' % settings['device'])
dprint('  Device Label: %s' % settings['label'])
dprint('  Resolution:   %d x %d pixels' % settings['size'])
dprint('  Frame Rate:   %d fps' % settings['rate'])
dprint('  Storage Path: %s' % settings['path'])

dprint('Initializing recorder...')

source = FrameGrabber(
    device = settings['device'], 
    size = settings['size'], 
    framerate = settings['rate'])
source.motion_detection = True

logfile = os.path.join(settings['path'], 'logfile.dat')
dbfile = os.path.join(settings['path'], 'frames.db')

recorder = Recorder(source, storage_path=settings['path'], logfile=logfile, 
    dbfile=dbfile)
recorder.connect('frame-added', on_frame_added)
recorder.connect('motion-detected', on_motion_detected)       

dprint('Starting to record in "%s"...' % settings['path'])
dprint('Press Ctrl+C to stop.')

while True:
    try:
        time.sleep(0.1)
    except KeyboardInterrupt:
        dprint('Stopping recorder...')
        source.stop()
        sys.exit(0)

